/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.jdbc;

import java.sql.SQLException;

public abstract class JDBCPrimaryKeyTestSetup extends JDBCDelegatingTestSetup {

    protected JDBCPrimaryKeyTestSetup(JDBCTestSetup delegate) {
        super(delegate);
    }

    @Override
    protected final void setUpData() throws Exception {
        // kill all the data
        try {
            dropAutoGeneratedPrimaryKeyTable();
        } catch (SQLException e) {
        }
        try {
            dropSequencedPrimaryKeyTable();
        } catch (SQLException e) {
        }
        try {
            dropNonIncrementingPrimaryKeyTable();
        } catch (SQLException e) {
        }
        try {
            dropMultiColumnPrimaryKeyTable();
        } catch (SQLException e) {
        }
        try {
            dropNullPrimaryKeyTable();
        } catch (SQLException e) {
        }
        try {
            dropUniqueIndexTable();
        } catch (SQLException e) {
        }

        try {
            dropNonFirstPrimaryKeyTable();
        } catch (SQLException e) {
        }

        // create all the data
        createAutoGeneratedPrimaryKeyTable();
        createSequencedPrimaryKeyTable();
        createNonIncrementingPrimaryKeyTable();
        createMultiColumnPrimaryKeyTable();
        createNullPrimaryKeyTable();
        createUniqueIndexTable();
        createNonFirstColumnPrimaryKey();
    }

    /** Drops the "auto" table. */
    protected abstract void dropAutoGeneratedPrimaryKeyTable() throws Exception;

    /** Drops the "uniq" table. */
    protected abstract void dropUniqueIndexTable() throws Exception;

    /** Drops the "seq" table. */
    protected abstract void dropSequencedPrimaryKeyTable() throws Exception;

    /** Drops the "noninc" table. */
    protected abstract void dropNonIncrementingPrimaryKeyTable() throws Exception;

    /** Drops the "multi" table. */
    protected abstract void dropMultiColumnPrimaryKeyTable() throws Exception;

    /** Drops the "nokey" table. */
    protected abstract void dropNullPrimaryKeyTable() throws Exception;

    /** Drops the "nonfirst" table. */
    protected abstract void dropNonFirstPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with auto-incrementing primary key column, which has the following schema:
     *
     * <p>auto( name:String; geom:Geometry; )
     *
     * <p>The table should be populated with the following data: "one" | NULL ; pkey = 1 "two" |
     * NULL ; pkey = 2 "three" | NULL ; pkey = 3
     */
    protected abstract void createAutoGeneratedPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with a unique index on one of the columns, which has the following schema:
     *
     * <p>uniq( key:Integer, name:String; geom:Geometry; )
     *
     * <p>The table should be populated with the following data: 1, "one" | NULL 2, "two" | NULL 3,
     * "three" | NULL
     */
    protected abstract void createUniqueIndexTable() throws Exception;

    /**
     * Creates a table with a primary key column with an associated sequence, which has the
     * following schema:
     *
     * <p>seq( name:String; geom:Geometry; )
     *
     * <p>The table should be populated with the following data: "one" | NULL ; pkey = 1 "two" |
     * NULL ; pkey = 2 "three" | NULL ; pkey = 3
     */
    protected abstract void createSequencedPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with a non incrementing primary key column, which has the following schema:
     *
     * <p>noninc( name:String; geom:Geometry; )
     *
     * <p>The table should be populated with the following data: "one" | NULL ; pkey = 1 "two" |
     * NULL ; pkey = 2 "three" | NULL ; pkey = 3
     */
    protected abstract void createNonIncrementingPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with a primary key which is made up of multiple columns, which has the
     * following schema:
     *
     * <p>multi( name:String, geom: Geometry );
     *
     * <p>The table should be populated with the following data: "one" | NULL ; pkey1 = 1, pkey2 =
     * 'x' "two" | NULL ; pkey1 = 1, pkey2 = 'y' "three" | NULL ; pkey1 = 1, pkey2 = 'z'
     */
    protected abstract void createMultiColumnPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with a primary key which is made up of multiple columns, which has the
     * following schema:
     *
     * <p>nokey( name:String );
     *
     * <p>The table should be populated with the following data: "one" "two" "three"
     */
    protected abstract void createNullPrimaryKeyTable() throws Exception;

    /**
     * Creates a table with a primary key that is not the first column the table.
     *
     * <p>nonfirst( name:String, key:Integer; geom:Geometry; );
     *
     * <p>The table should be populated with the following data: "one", 1, NULL "two", 2, NULL
     * "three", 3, NULL
     */
    protected abstract void createNonFirstColumnPrimaryKey() throws Exception;
}
